<template>
  <div>
    <el-upload
      ref="excel-upload"
      class="upload-demo"
      drag
      accept=".xlsx, .xls, .csv"
      action="#"
      :auto-upload="false"
      :before-remove="beforeRemove"
      :on-change="onChange"
    >
      <i class="el-icon-upload" />
      <div class="el-upload__text">{{ $t('button.dropExcel') }}<em>{{ $t('button.browse') }}</em></div>
      <div slot="tip" class="el-upload__tip">{{ $t('tip.excelUploadTip') }}{{ fileSizeLimit }}MB</div>
    </el-upload>
  </div>
</template>
<script>
import XLSX from 'xlsx'
export default {
  name: 'Excel',
  props: {
    beforeUpload: Function, // eslint-disable-line
    excelData: {
      type: Object,
      default: null
    },
    fileSizeLimit: {
      type: Number,
      default: 0.1
    },
    headers: {
      type: Array,
      required: true
    }
  },
  data() {
    return {
      loading: false
    }
  },
  methods: {
    generateData(val) {
      if (!val.results.length) {
        (async() => {
          await new Promise(resolve => {
            this.$message({
              message: this.$t('tip.excelEmpty'),
              type: 'warning',
              duration: 1000
            })
            setTimeout(resolve, 1300)
          })
          this.$refs['excel-upload'].clearFiles()
        })()
        return
      }
      this.$emit('update:excelData', val)
    },
    beforeRemove(file) {
      // this.generateData(null)
      return this.$confirm(`确定移除 ${file.name}？`)
    },
    onChange(file) {
      const hasFile = this.$refs['excel-upload'].uploadFiles.length > 1 // 此时是否已有文件
      if (!this.isExcel(file)) {
        if (hasFile) {
          this.$refs['excel-upload'].uploadFiles.splice(1, 1) // 移除刚添加的文件
        } else {
          this.$refs['excel-upload'].clearFiles() // 移除全部文件
        }
        this.$message({
          message: this.$t('tip.onlyExcel'),
          type: 'warning',
          duration: 1000
        })
        return
      }
      if (!this.beforeUpload(file)) {
        if (hasFile) {
          this.$refs['excel-upload'].uploadFiles.splice(1, 1) // 移除刚添加的文件
        } else {
          this.$refs['excel-upload'].clearFiles() // 移除全部文件
        }
        return
      }
      if (hasFile) {
        this.$refs['excel-upload'].uploadFiles.splice(0, 1) // 移除前一个
      }
      // 解析文件
      this.loading = true
      this.readerData(this.$refs['excel-upload'].uploadFiles[0].raw).then(results => {
        this.generateData({ results })
      }).catch(() => {
        (async() => {
          await new Promise(resolve => {
            this.$message({
              message: this.$t('tip.excelFormatError'),
              type: 'warning',
              duration: 1000
            })
            setTimeout(resolve, 1300)
          })
          this.$refs['excel-upload'].clearFiles()
        })()
      }).finally(() => {
        this.loading = false
      })
    },
    readerData(rawFile) {
      return new Promise((resolve, reject) => {
        const reader = new FileReader()
        reader.onload = e => {
          const data = e.target.result
          const workbook = XLSX.read(data, { type: 'array', cellDates: true })
          // 获取工作簿中的第一个工作表名字
          const firstSheetName = workbook.SheetNames[0]
          // 获取对应的工作表对象
          const worksheet = workbook.Sheets[firstSheetName]
          const _headers = this.getHeaderRow(worksheet)
          const excelFormat = (() => {
            if (this.headers.length !== _headers.length) {
              return false
            }
            for (const h of this.headers) {
              if (!_headers.includes(h)) {
                return false
              }
            }
            return true
          })()
          if (!excelFormat) {
            reject()
          }
          const results = XLSX.utils.sheet_to_json(worksheet, { header: 1 })
          // 删除第一项
          results.splice(0, 1)
          // 若是String去除前后空格
          resolve(results.map(array => {
            return array.map(item => {
              if (typeof (item) === 'string') {
                return item.trim()
              } else {
                return item
              }
            })
          }))
        }
        reader.readAsArrayBuffer(rawFile)
      })
    },
    getHeaderRow(sheet) {
      const headers = []
      const range = XLSX.utils.decode_range(sheet['!ref'])
      let C
      const R = range.s.r
      for (C = range.s.c; C <= range.e.c; ++C) { /* walk every column in the range */
        const cell = sheet[XLSX.utils.encode_cell({ c: C, r: R })]
        /* find the cell in the first row */
        let hdr = 'UNKNOWN ' + C // <-- replace with your desired default
        if (cell && cell.t) hdr = XLSX.utils.format_cell(cell)
        headers.push(hdr.trim())
      }
      return headers
    },
    isExcel(file) {
      return /\.(xlsx|xls|csv)$/.test(file.name)
    }
  }
}
</script>
<style scoped>
</style>
